package drawables;

import game.Camera;

import java.util.LinkedList;
import java.util.Queue;

import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;

import player.Player;

public class PlayerDrawable implements Drawable<Player> {
	
	private static final int MAX_OVERLAYS = 20, MAX_ROTATION_SPEED = 10, DEATH_TIME = 60;
	private static final float MIN_ROTATION_SPEED = 0.3f;
	
	private Image playerDark, playerGlow, playerDeath;
	private Queue<State> overlays = new LinkedList<State>();
	private float previousRotation;
	private int deadTimeElapsed;
	
	public PlayerDrawable() throws SlickException{
		playerDark = new Image("resources/player/player.png");
		playerDark.setCenterOfRotation(75, 75);
		playerGlow = new Image("resources/player/player_glow.png");
		playerGlow.setCenterOfRotation(75, 75);
		playerDeath = new Image("resources/player/player_death.png");
		playerDeath.setCenterOfRotation(100, 100);
	}

	@Override
	public void draw(Graphics g, Camera camera) {
		float offsetX = camera.getOffsetX();
		float offsetY = camera.getOffsetY();
		if(overlays.isEmpty())
			return;
		float globalAlpha = 1f/overlays.size();
		if(deadTimeElapsed > 0)
			globalAlpha = 1f/MAX_OVERLAYS;
		Color globalFilter = new Color(globalAlpha, globalAlpha, globalAlpha);
		g.setDrawMode(Graphics.MODE_ADD);
		for(State state : overlays){
			if(state.dead){
				playerDeath.setRotation(state.rotation);
				float alpha = globalAlpha * (float)(Math.random() * 0.8 + 0.6);
				playerDeath.draw(state.x+offsetX-100, state.y+offsetY-100, new Color(alpha, alpha, alpha));
			} else{
				playerDark.setRotation(state.rotation);
				playerGlow.setRotation(state.rotation);
				float alpha = globalAlpha * state.visibility * (float)(Math.random() * 0.8 + 0.6);
				playerDark.draw(state.x+offsetX-75, state.y+offsetY-75, globalFilter);
				playerGlow.draw(state.x+offsetX-75, state.y+offsetY-75, new Color(alpha, alpha, alpha));
			}
		}
		g.setDrawMode(Graphics.MODE_NORMAL);
	}

	@Override
	public void update(Player player) {
		if(overlays.size() >= MAX_OVERLAYS)
			overlays.poll();
		if(deadTimeElapsed > DEATH_TIME && !overlays.isEmpty()){
			overlays.poll();
			return;
		}
		State newState = new State();
		newState.x = player.getX();
		newState.y = player.getY();
		newState.visibility = player.visibility();
		newState.rotation = Math.max((previousRotation + MAX_ROTATION_SPEED * player.sprintCharge()), previousRotation + MIN_ROTATION_SPEED) % 360;
		newState.dead = player.isDead();
		previousRotation = newState.rotation;
		overlays.offer(newState);
		if(player.isDead() && deadTimeElapsed <= DEATH_TIME)
			deadTimeElapsed++;
	}
	
	private static class State{
		float visibility, x, y, rotation;
		boolean dead;
	}
}
